import { director, Prefab, SpriteFrame, Vec3, Node } from "cc";
import Singleton from "../Base/Singleton";
import { IActor, IActorMove, IBullet, IClientInput, IState } from "../Common/State";
import { JoyStickmanager } from "../UI/JoyStickmanager";
import { ActorManager } from "../Entity/Actor/ActorManager";
import { EntityTypeEnum, InputTypeEnum, IRoom, toFixed } from "../Common";
import { BulletManager } from "../Entity/Bullet/BulletManager";
import EventManager from "./EventManager";
import { EventEnum } from "../Enum";

const ACTOR_SPEED = 100;//角色速度
const BULLET_SPEED = 600;//子弹速度

const MaP_WIDTH = 960;
const MaP_HEIGHT = 640;//地图大小

const ACTOR_RADIUS = 40;//角色半径
const BULLET_RADIUS = 10;//子弹半径

const BULLET_DAMAGE = 5;//子弹伤害

export default class DataManager extends Singleton {


  static get Instance() {
    return super.GetInstance<DataManager>();
  }

  roomIP: string;//房间ip

  myPlayerId: number = 1;//自己id
  frameId: number = 1;
  roomInfo:IRoom;//房间信息

  stage: Node;//舞台
  public jm: JoyStickmanager;//摇杆
  actorMap: Map<number, ActorManager> = new Map();//角色管理器
  bulletMap: Map<number, BulletManager> = new Map();
  prefabMap: Map<string, Prefab> = new Map();//预设体管理器 游戏一开始把各个预制体加载好
  textureMap: Map<string, SpriteFrame[]> = new Map();//贴图管理器 角色贴图加载好

  lastState: IState //之前状态

  state: IState = {
    // 角色信息
    actor: [
      // {
      //   id: 1,
      //   type: EntityTypeEnum.Actor1,
      //   weaponType: EntityTypeEnum.Weapon1,
      //   bulletType: EntityTypeEnum.Bullet2,
      //   hp: 100,
      //   position: {
      //     x: 0,
      //     y: 0,
      //     z: 0
      //   },
      //   direction: {
      //     x: 1,
      //     y: 0,
      //     z: 0
      //   },
      // },
      // {
      //   id: 2,
      //   type: EntityTypeEnum.Actor1,
      //   weaponType: EntityTypeEnum.Weapon1,
      //   bulletType: EntityTypeEnum.Bullet2,
      //   hp: 100,
      //   position: {
      //     x: -150,
      //     y: -150,
      //     z: 0
      //   },
      //   direction: {
      //     x: -1,
      //     y: 0,
      //     z: 0
      //   },
      // },
    ],
    bullet: [],
    nextBulletId: 1,

  }


  applyInput(input: IClientInput) {
    switch (input.type) {
      //角色移动
      case InputTypeEnum.ActorMove: {
        const {
          id,
          dt,
          direction: { x, y, z }
        } = input;

        const actor = this.state.actor.find((e) => e.id == id);
        actor.direction = new Vec3(x, y, z);

        actor.position.x = actor.position.x + toFixed(x * dt * ACTOR_SPEED);
        actor.position.y = actor.position.y + toFixed(y * dt * ACTOR_SPEED);
        actor.position.z = actor.position.z + toFixed(z * dt * ACTOR_SPEED);
        break;
      }
      //枪
      case InputTypeEnum.WeaponShoot: {
        const {
          owner,
          position,
          direction
        } = input;
        const bullet: IBullet = {
          id: this.state.nextBulletId++,
          owner,
          position,
          direction,
          type: this.actorMap.get(owner).bulletType,
        }
        EventManager.Instance.emit(EventEnum.BulletBorn, owner);//分发事件
        this.state.bullet.push(bullet);
        break;
      }
      //子弹
      case InputTypeEnum.TimePast: {
        const {
          dt
        } = input;
        const { bullet, actor } = this.state;
        for (let i = bullet.length - 1; i >= 0; i--) {
          const bullett = bullet[i];

          for (let j = actor.length - 1; j >= 0; j--) {
            const actorr = actor[j];
            if(actorr.id==bullett.owner){
              continue;
            }
            if(((actorr.position.x-bullett.position.x)**2+(actorr.position.y-bullett.position.y)**2)<
              (ACTOR_RADIUS+BULLET_RADIUS)**2){
                actorr.hp-=BULLET_DAMAGE;
            EventManager.Instance.emit(EventEnum.ExplosionBorn, bullett.id, 
              { x: toFixed(bullett.position.x+actorr.position.x)/2,
                y: toFixed(bullett.position.y+actorr.position.y)/2,
              });
              bullet.splice(i, 1);
              break;
          }
          }

          if (Math.abs(bullett.position.x) > MaP_WIDTH / 2 || Math.abs(bullett.position.y) > MaP_HEIGHT / 2) {
            EventManager.Instance.emit(EventEnum.ExplosionBorn, bullett.id, { x: bullett.position.x, y: bullett.position.y, z: bullett.position.z });
            bullet.splice(i, 1);
            break;
          }
        }

        for (const bullett of bullet) {
          bullett.position.x = bullett.position.x + toFixed(bullett.direction.x * dt * BULLET_SPEED);
          bullett.position.y = bullett.position.y + toFixed(bullett.direction.y * dt * BULLET_SPEED);
          0;
        }
      }
    }

  }
}
